using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;

namespace Lds.Ward.PhotoDirectory.Logic
{
	public class PostalAddress
	{
		public PostalAddress() { }

		private string streetAddress;

		public string StreetAddress
		{
			get { return streetAddress; }
			set { streetAddress = value; }
		}

		private string apartmentNumber;

		public string ApartmentNumber
		{
			get { return apartmentNumber; }
			set { apartmentNumber = value; }
		}

		private string city;

		public string City
		{
			get { return city; }
			set { city = value; }
		}

		private string state;

		public string State
		{
			get { return state; }
			set { state = value; }
		}

		private string postalCode;

		public string PostalCode
		{
			get { return postalCode; }
			set { postalCode = value; }
		}

		private string original;

		public string Original
		{
			get { return original; }
			set { original = value; }
		}

		public static PostalAddress Parse(string original)
		{
			string postalRegex = @"(?<zip>\d{5}(?:-\d{4})?)";
			string stateRegex = @"(?:(?<state>[A-Z]{2}))|(?:, (?<state>[A-z ]+))";
			string cityRegex = @"\n(?<city>[\w ]+), ";
			string aptRegex = @"(?:Apt\.? #?(?<apt>\w+))|(?:#(?<apt>\w+))";
			string streetAddressRegex = @"(?<street>[\w \.]+)";

			PostalAddress addr = new PostalAddress();
			addr.Original = original;
			Match m = Regex.Match(original, aptRegex);
			if (m.Success) addr.ApartmentNumber = m.Groups["apt"].Value.Trim();
			m = Regex.Match(original, stateRegex);
			if (m.Success) addr.State = m.Groups["state"].Value.Trim();
			m = Regex.Match(original, streetAddressRegex);
			if (m.Success)
			{
				addr.StreetAddress = m.Groups["street"].Value.Trim();
				Match aptM = Regex.Match(addr.StreetAddress, @"\Wapt\.? *#?\d+|\Wapt\.?$", RegexOptions.IgnoreCase);
				if (aptM.Success) addr.StreetAddress = addr.StreetAddress.Substring(0, aptM.Index).Trim();
			}
			m = Regex.Match(original, cityRegex);
			if (m.Success) addr.City = m.Groups["city"].Value.Trim();
			m = Regex.Match(original, postalRegex);
			if (m.Success) addr.PostalCode = m.Groups["zip"].Value.Trim();
			return addr;
		}

		public override string ToString()
		{
			return string.Format("{0} {1}{2}{3}, {4} {5}",
				StreetAddress, ApartmentNumber != null && ApartmentNumber.Length > 0 ? "#" + ApartmentNumber : "", 
				Environment.NewLine, City, State, PostalCode);
		}
	}
}
